<script setup>
import { ref, computed, watch } from "vue"
import { useRoute, useRouter } from "vue-router"
import { getDetailInfos } from "@/services"
import { useScroll } from "@/hooks/useScroll"

import TabControl from "@/components/tab-control/tab-control.vue"
import DetailSwipe from "./cpns/detail_01-swipe.vue"
import DetailInfos from "./cpns/detail_02-infos.vue"
import DetailFacility from "./cpns/detail_03-facility.vue"
import DetailLandlord from "./cpns/detail_04-landlord.vue"
import DetailComment from "./cpns/detail_05-comment.vue"
import DetailNotice from "./cpns/detail_06-notice.vue"
import DetailMap from "./cpns/detail_07-map.vue"
import DetailIntro from "./cpns/detail_08-intro.vue"

const router = useRouter()
const route = useRoute()

// 返回首页
const onClickLeft = () => {
  router.back()
}


// 发送网络请求
const detailInfos = ref({})
// 从返回的数据中提取目标数据
const houseId = route.params.id
const mainPart = computed(() => detailInfos.value?.mainPart)
getDetailInfos(houseId).then(res => {
  detailInfos.value = res.data.data
})

// console.log(mainPart)

// tabControl相关的操作
// 根据滚动的长度决定显示/隐藏
const detailRef = ref()
const { scrollTop } = useScroll(detailRef)
const showTabControl = computed(() => scrollTop.value > 300)

// 获取单个ref，ref属性的属性值为 string
// const landlordRef = ref()
// 获取多个ref，ref属性的属性值为 Function，注意格式为 :ref="Function"
// 获取多个 ref，给需要的组件绑定同一个函数 :ref="Function"
// 绑定好后，该函数会自动自行一次，《将绑定元素作为参数传入函数》
const sectionEles = ref({})
const names = computed(() => {
  // 获取 sectionEles 对象所有的 key，返回一个包含所有key的数组
  return Object.keys(sectionEles.value)
})

const getSectionRef = (el) => {
  // 注意：在组件被卸载时，也会执行一次当前函数，这时传入的参数为 null
  if(!el) return

  // ele.getAttribute("name") 获取元素的name属性
  // 使用 组件元素.$el的方式获取该组件的根节点
  // sectionEles 对象的 key 为组件的 name 属性值，value 为组件的根节点
  const name = el.$el.getAttribute("name")
  sectionEles.value[name] = el.$el
}

let isClick = false
let curretDistance = -1
// tab 点击时的处理函数
const tabClick = (index) => {
  const key = Object.keys(sectionEles.value)[index]
  const el = sectionEles.value[key]
  let distance = el.offsetTop
  // 调整第一个区域的显示问题
  if(index !== 0) {
    // 减去 tab-control 组件的高度 44px
    distance = distance - 44
  }

  isClick = true
  curretDistance = distance

  // elem.scrollTo()：设置元素elem的滚动距离
  detailRef.value.scrollTo({
    top: distance,
    // 平滑滚动（有一个动画的效果）
    behavior: "smooth"
  })

  if(detailRef.value.scrollTop === distance) isClick = false
}

// 页面滚动，滚动时匹配对应的tabControl的index
const tabControlRef = ref()
watch(scrollTop, (newValue) => {
  // 如果正在点击时，不进行任何操作（避免点击tab时，触发当前事件）
  if(newValue === curretDistance) {
    isClick = false
  }
  if(isClick) return

  // Object.values(sectionEles) 将对象sectionEles的全部value封装到一个数组后，将其返回
  // 1.获取所有区域的offsetTop
  const els = Object.values(sectionEles.value)
  const values = els.map(el => el.offsetTop)

  // 2.根据 newValue 去匹配对应的索引
  /*
    算法的实现原理：
      根据一个一直在变化的值去数组中查找自己的位置（索引值）
  */
  let index = values.length - 1 // 匹配最后一个 tab 的索引值
  for(let i = 0; i < values.length; i++) {
    // 加上原来减去的 44px
    if(values[i] > newValue + 44) {
      index = i - 1
      break
    }
  }
  // console.log(index)
  // 使用可选链操作符，避免组件未被挂载时，导致的报错
  // 暂时的总结：暴露的方法可以使用，但是属性使用不了
  tabControlRef.value?.setCurrentIndex(index)
  // tabControlRef.value?.currentIndex.value = index // 报错
})
</script>

<template>
  <div ref="detailRef" class="detail top-page">
    <!-- 顶部 tab 栏 -->
    <tab-control 
      class="tabs" 
      v-if="showTabControl"
      @tab-item-click="tabClick"
      ref="tabControlRef"
      :titles="names"/>
    <!-- 导航栏 -->
    <van-nav-bar title="房屋详情" left-text="旅途" left-arrow @click-left="onClickLeft" />

    <!-- 当 mainPart 有数据时，才显示该组件 -->
    <!-- 优化：v-memo="[mainPart]" 表示当 mainPart 对象发生变化时，当前元素的内部元素才会发生刷新 -->
    <div class="main" v-if="mainPart" v-memo="[mainPart]">
      <!-- 轮播图 -->
      <detail-swipe :swipe-data="mainPart.topModule.housePicture.housePics" />
      <!-- 信息展示 -->
      <detail-infos name="描述" :ref="getSectionRef" :top-infos="mainPart.topModule" />
      <detail-facility name="设施" :ref="getSectionRef" :house-facility="mainPart.dynamicModule.facilityModule.houseFacility" />
      <detail-landlord name="房东" :ref="getSectionRef" :landlord="mainPart.dynamicModule.landlordModule" />
      <detail-comment name="评论" :ref="getSectionRef" :comment="mainPart.dynamicModule.commentModule" />
      <detail-notice name="须知" :ref="getSectionRef" :order-rules="mainPart.dynamicModule.rulesModule.orderRules" />
      <detail-map name="周边" :ref="getSectionRef" :position="mainPart.dynamicModule
      .positionModule" />
      <detail-intro :intro="mainPart.introductionModule" />
      <div class="footer">
        <img src="@/assets/img/detail/icon_ensure.png" alt="">
        <div class="text">弘源旅途, 永无止境!</div>
      </div>
    </div>

  </div>
</template>

<style lang="less" scoped>
.tabs {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 9;
}

.detail {
  --van-nav-bar-title-text-color: var(--primary-color);

  // 使用 :deep() 设置子组件（vant组件）的样式才会生效
  :deep(.van-nav-bar__title) {
    font-weight: 400;
  }

  .footer {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 120px;

    img {
      width: 123px;
    }

    .text {
      margin-top: 12px;
      font-size: 12px;
      color: #7688a7;
    }
  }
}
</style>